package org.mendoza.salud.hvt.server.global;


import org.mendoza.salud.hvt.client.shared.model.AbstractEntity;

import javax.annotation.PostConstruct;
import javax.ejb.Stateless;
import javax.persistence.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: ricardo
 * Date: 12/11/13
 * Time: 11:20
 * To change this template use File | Settings | File Templates.
 */
@Stateless
public class PersistenceServiceBean {

    @PersistenceContext
    public EntityManager entityManager;


    public PersistenceServiceBean() {
    }

    @PostConstruct
    public void init() {
    }

    public <T extends AbstractEntity> T persist(T entidad) {
        if (entidad != null) {
            entityManager.persist(entidad);
            entityManager.flush();
        }
        return entidad;
    }

    public void persistEntity(AbstractEntity entity) {
        entityManager.persist(entity);
    }

    public <T extends AbstractEntity> T merge(T entidad) {
        if (entidad != null) {
            entidad = entityManager.merge(entidad);
        }
        return entidad;
    }


    public <T extends AbstractEntity> List<T> find(String nombreBusqueda, Map<String, Object> parametros) {
        try {
            return parseQuery(nombreBusqueda, parametros).getResultList();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public <T extends AbstractEntity> T findUnique(String nombreBusqueda, Map<String, Object> parametros) {
        try {
            return (T) parseQuery(nombreBusqueda, parametros).getSingleResult();
        } catch (NoResultException nre) {
            return null;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public <T extends AbstractEntity> T findUnique(String nombreBusqueda, String nombreParametro, Object parametro) {
        HashMap<String, Object> parametros = new HashMap<String, Object>();
        parametros.put(nombreParametro, parametro);
        return findUnique(nombreBusqueda, parametros);
    }

    private Query parseQuery(String nombreBusqueda, Map<String, Object> parametros) {
        try {
            Query busqueda = entityManager.createNamedQuery(nombreBusqueda);
            if (parametros != null) {
                for (Parameter parameter : busqueda.getParameters()) {
                    busqueda.setParameter(parameter, parametros.get(parameter.getName()));
                }
            }
            return busqueda;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public <T extends AbstractEntity> T findById(T entidad) {
        return (T) entityManager.find(entidad.getClass(), entidad.getId());
    }

    public <T extends AbstractEntity> List<T> findAll(String nombreBusqueda) {
        return find(nombreBusqueda, new HashMap<String, Object>());
    }

    public <T extends AbstractEntity> List<T> find(String nombreBusqueda, String nombreParametro, Object parametro) {
        Map<String, Object> parametros = new HashMap<String, Object>();
        parametros.put(nombreParametro, parametro);
        return find(nombreBusqueda, parametros);
    }
}
